// This file is part of SyncStar, free software released under GPL v2.
package com.syncstar;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;

/** Service to call SmsUtils.populatePresenceTable() in a dedicated thread,
 * possibly delayed in time (for batching and throttling to avoid excessive
 * CPU usage).
 */
public class PopulateService extends IntentService {
  private static final String TAG = SmsUtils.class.getSimpleName();

  static final int DEFAULT_POPULATE_INTERVAL_MS = 30000;  // TODO: 30 seconds.
  static final int MIN_POPULATE_INTERVAL_MS = 10000;

  public PopulateService() {
    super("FooPopulateService");  // This name doesn't matter.
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    Log.e(TAG, "CONNX handle PopulateService");
    SharedPreferences spConfig = getSharedPreferences("config", 0);
    final int interval = Math.max(MIN_POPULATE_INTERVAL_MS,
        spConfig.getInt("populate_interval_ms", DEFAULT_POPULATE_INTERVAL_MS));
    // Don't populate if it has been populated recently.
    SmsUtils.populatePresenceTable(this, interval - 1000);
  }

  static void populatePresenceTableNowOrLater(Context context) {
    final SharedPreferences spConfig = context.getSharedPreferences("config", 0);
    final int interval = Math.max(MIN_POPULATE_INTERVAL_MS,
        spConfig.getInt("populate_interval_ms", DEFAULT_POPULATE_INTERVAL_MS));
    final SharedPreferences spLastpopulate = context.getSharedPreferences("lastpopulate", 0);
    final long lastPopulateAt = spLastpopulate.getLong("last", Long.MIN_VALUE);
    final long lastPopulateAgo = lastPopulateAt == Long.MIN_VALUE ?
        Long.MAX_VALUE : System.currentTimeMillis() - lastPopulateAt;
    // We don't care if doSync is running, because we want to populate
    // even then, since the doSync might fail early, and then it won't populate.
    //
    // Let's suppose that messages keep coming during our `interval'. In that
    // case we call populatePresenceTable() every `interval' milliseconds.
    final long nextPopulateAt = lastPopulateAgo >= interval ? 0 :
        interval - lastPopulateAgo;
    Log.e(TAG, "CONNX maybePopulate lastAgo=" + lastPopulateAgo +
               " interval=" + interval +
               " nextAt=" + nextPopulateAt);
    // It would be tempting to do this:
    //
    //   if (nextPopulateAt <= 0) {
    //     SmsUtils.populatePresenceTable(context, -1);
    //     return;
    //   }
    //
    // , but scheduling it to right now with the AlarmManager below has the
    // advantage that the populatePresenceTable is run in a dedicated thread,
    // not blocking the UI thread for half a second.
    final Intent scheduledIntent = new Intent(context, PopulateService.class);
    final PendingIntent pendingIntent = PendingIntent.getService(
        context, SyncService.REQUEST_CODE_POPULATE, scheduledIntent,
        PendingIntent.FLAG_UPDATE_CURRENT);
    ((AlarmManager)context.getSystemService(ALARM_SERVICE)).set(
        AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + nextPopulateAt,
        pendingIntent);
  }
}
